package tsing.javase.thread.pool.pratice;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


import java.util.concurrent.*;

/**
 * @Date 2024/1/26 14:09
 * 使用ThreadFactory创建可复用的线程池，同时配置捕获异常
 */
@Configuration
public class ReusableThreadPool {


    @Bean
    public ThreadPoolExecutor  getThreadPool(){
        // 核心线程数
        int corePoolSize = 10;
        // 最大线程数
        int maximumPoolSize = 350;
        // 空闲线程等待新任务的最长时间（单位：秒）
        long keepAliveTime = 60L;
        // 时间单位
        TimeUnit unit = TimeUnit.SECONDS;
        // 任务队列
        BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>(1000);
        // 线程工厂
//        ThreadFactory threadFactory = Executors.defaultThreadFactory();
        ThreadFactory threadFactory = getThreadFactoryMethod();
        // 拒绝策略
        RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
        return new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
    }


    /**
     * 自定义线程工程
     * @return
     */
    public ThreadFactory   getThreadFactoryMethod(){
        // 重写ThreadFactory的 newThread()方法，定义线程
        ThreadFactory factory = new ThreadFactory() {
            private int counter = 0;
            @Override
            public Thread newThread(Runnable r) {
                Thread t = new Thread(r);
                // 设置线程的名字
                t.setName("订购-" + counter++);
                t.setUncaughtExceptionHandler(new CommonThreadExceptionHandle()); //设置异常处理
                return t;
            };



        };
        return factory;
    }


    /**
     * @Date 2024/1/26 16:16
     *
     * 全局线程异常处理
     */
    public class CommonThreadExceptionHandle implements  Thread.UncaughtExceptionHandler{
        @Override
        public void uncaughtException(Thread t, Throwable e) {
            // 捕获，记录异常
            System.out.println("捕获异常： "+e);
        }
    }



    public static void main(String[] args) {
        // 测试
        ReusableThreadPool bean = new ReusableThreadPool();
        ThreadPoolExecutor threadPool = bean.getThreadPool();

        for (int i = 0; i <20 ; i++) {
            String index = i+"";
            threadPool.execute(()->{
                System.out.println("任务 " + index + " 由 " + Thread.currentThread().getName() + " 执行");
                if("2".equals(index)){
                    System.out.println(5 / 0);
                }

              }

            );
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }


        }
        // 关闭线程池
        threadPool.shutdown();

    }
}
